/**
 * @author Ahammer
 * @date 2009 04
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package op;

import ij.IJ;
import ij.ImagePlus;
import ij.process.ImageStatistics;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.renderable.ParameterBlock;

import javax.media.jai.BorderExtender;
import javax.media.jai.JAI;
import javax.media.jai.KernelJAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import main.Board;

/**
 * This is the main image processing class
 * There exist two approaches:
 * A user defined JAI operator is just called 
 * or:
 * The actual processing is implemented in this class 
 */
public class IqmUnsharpMaskOperator{ 


  public IqmUnsharpMaskOperator() {
	  //WARNING: Don't declare fields here
	  //Fields declared here aren't thread safe!   
  }
  /**
   * 
   * @param ParametrBlockJAI pb
   */
  public Object run(ParameterBlockJAI pbJAI){
	  Object ob = null;
	  PlanarImage pi = (PlanarImage) pbJAI.getRenderedSource(0);
	  int kernelSize = pbJAI.getIntParameter("KernelSize");
	  float gain     = (float)pbJAI.getIntParameter("Gain")/10.0f;
	  int size = kernelSize*kernelSize;
	  float[] kernel = new float[size];
	  //********************************************************
	  int method = 1;
	  //********************************************************	  
	  if (method == 0){ //Mean
		  for (int i = 0; i < kernelSize; i++) {
			  for ( int j = 0; j < kernelSize; j++) {
				  kernel[i*kernelSize + j] = 1.0f/size;
			  }
		  }
	  }
	  if (method == 1){ //Gauss
		  float radius = (kernelSize-1)/2;
		  float sigma = radius;
		  float total = 0.0f;
		  for (int i = 0; i < kernelSize; i++) {
			  for ( int j = 0; j < kernelSize; j++) {
				  kernel[i*kernelSize + j] = (float) ((Math.exp(-0.5*((i-radius)*(i-radius) + (j-radius)*(j-radius))/(sigma*sigma))) / (2*Math.PI*(sigma*sigma)));
				  total = total + kernel[i*kernelSize + j];
			  }
		  }
		  for (int i =0; i < kernel.length; i++){
			  kernel[i] = kernel[i] / total;
		  }
	  }
	  KernelJAI kernelJAI = new KernelJAI(kernelSize, kernelSize, kernel);  
	  //System.out.println(KernelUtil.kernelToString(kernelJAI, true));

	  RenderingHints rh = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));
	  ParameterBlock pb = new ParameterBlock();
	  pb.addSource(pi);
	  pb.add(kernelJAI);
	  pb.add(gain);

      ob = JAI.create("UnsharpMask", pb, rh);
	  return ob;
  }
}
